package com.zbl.zblproject.pay.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.AlipayTradePayRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPayResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.zbl.zblproject.core.entity.AdminUser;
import com.zbl.zblproject.core.entity.SnowFlake;
import com.zbl.zblproject.core.mapper.AdminUserMapper;
import com.zbl.zblproject.core.mapper.SmallUnitMapper;
import com.zbl.zblproject.core.mapper.SupplierMapper;
import com.zbl.zblproject.core.utils.StringUtil;
import com.zbl.zblproject.erp.entity.ErpGoods;
import com.zbl.zblproject.erp.entity.ErpWarehouseItem;
import com.zbl.zblproject.erp.mapper.ErpCategoryMapper;
import com.zbl.zblproject.erp.mapper.ErpGoodMapper;
import com.zbl.zblproject.erp.mapper.ErpWarehouseItemMapper;
import com.zbl.zblproject.pay.controller.PayComponent;
import com.zbl.zblproject.pay.entity.*;
import com.zbl.zblproject.pay.mapper.PayOrderItemMapper;
import com.zbl.zblproject.pay.mapper.PayOrderMapper;
import com.zbl.zblproject.pay.service.PayService;
import com.zbl.zblproject.pay.vo.PayOrderItemVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author youlanqiang
 * @version 1.0
 * @date 2018/11/5
 * 支付
 */
@Service
@Transactional
public class PayServiceImpl implements PayService {


    private static final Logger logger = LoggerFactory.getLogger(PayService.class);

    @Autowired
    private PayOrderMapper payOrderMapper;

    @Autowired
    private PayOrderItemMapper payOrderItemMapper;

    @Autowired
    private ErpGoodMapper erpGoodMapper;


    @Autowired
    private SnowFlake snowFlake;

    @Autowired
    private AlipayTradeService alipayTradeService;

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Autowired
    private PayComponent payComponent;

    @Autowired
    private SupplierMapper supplierMapper;

    @Autowired
    private SmallUnitMapper smallUnitMapper;

    @Autowired
    private ErpCategoryMapper erpCategoryMapper;

    @Autowired
    private ErpWarehouseItemMapper warehouseItemMapper;

    @Autowired
    private WeixinProperties weixinProperties;

    @Value("${pay.alipay.authToken}")
    private String authToken;

    @Override
    public boolean changeOrderToRefund(PayOrder order) {
        if(order.getStatus() == 0){
            return false;
        }
        order.setStatus(2);
        return payOrderMapper.updateById(order) == 1;
    }

    @Override
    public PayOrder getOrderByOnlineSn(String orderSn) {
        QueryWrapper<PayOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("online_order_sn", orderSn);
        return payOrderMapper.selectOne(wrapper);
    }

    @Override
    public void createBaseOrder(final AdminUser user, final PayOrder order) {
        if (order.getCreateTime() == null) {
            order.setCreateTime(LocalDateTime.now());
        }
        order.setUserId(user.getUserId());
        boolean result = payOrderMapper.insert(order) == 1;
        if (!result) {
            throw new RuntimeException("订单添加失败!");
        }


        //查询是否在订单明细表中生成过
        List<PayOrderItem> tem=payOrderItemMapper.selectListByOrderId(order.getId());
        if(null==tem||tem.isEmpty()) {
            for (PayOrderItem item : order.getItems()) {
                item.setId(snowFlake.nextId());
                item.setOrderId(order.getId());
                result = payOrderItemMapper.insert(item) == 1;
                Preconditions.checkArgument(result, "订单项添加失败!");
            }
        }

    }

    @Override
    public void createBaseOrderTwo(AdminUser user, PayOrder order) {

        if (order.getCreateTime() == null) {
            order.setCreateTime(LocalDateTime.now());
        }
        order.setUserId(user.getUserId());
        boolean result = payOrderMapper.insert(order) == 1;
        if (!result) {
            throw new RuntimeException("订单添加失败!");
        }

        //查询是否在订单明细表中生成过
        List<PayOrderItem> tem=payOrderItemMapper.selectListByOrderId(order.getId());
        if(null==tem||tem.isEmpty()){
        for (PayOrderItem item : order.getItems()){
            item.setId(snowFlake.nextId());
            item.setOrderId(order.getId());
            result = payOrderItemMapper.insert(item) == 1;
            Preconditions.checkArgument(result, "订单项添加失败!");
         }
        }







    }

    @Override
    public void subtract(List<PayOrderItem> items) {
        for(PayOrderItem x : items){

            ErpGoods goods = erpGoodMapper.selectById(x.getGoodsId());
            if(goods != null) {
                ErpWarehouseItem item = warehouseItemMapper.selectItemByGoodsIdAndWhId(x.getGoodsId(), 4);
                if (x.getGoodsNum() != 0) {
                    if (item != null) {
                        item.setStock(item.getStock() - (int)x.getGoodsNum());
                        warehouseItemMapper.updateById(item);
                    }
                    goods.setGoodsNumber(goods.getGoodsNumber() - (int)x.getGoodsNum());
                }
            }
        }

    }

    @Override
    public synchronized List<String> createBaseOrders(String sn, final AdminUser user, final List<PayOrder> orders) {
        if (orders.isEmpty()) {
            throw new RuntimeException("没有需要更新的订单项");
        }
        //日期码
        String flowNo = LocalDateTime.now()
                .format(DateTimeFormatter.ofPattern("yyyyMMdd")) + sn;
        //0: 现金 1:支付宝 2:微信 3:银联
        List<String> list = new ArrayList<>();
        for (PayOrder order : orders) {
            //设置订单流水号
            Long no =  payOrderMapper.selectFlowOrder(flowNo);
            if(no == null){
                order.setId(Long.valueOf(flowNo + "00001"));
            }else{
                String strNo = String.valueOf(no);
                String index = strNo.substring(strNo.length() - 5);
                if(index.equalsIgnoreCase("99999") ){
                    throw new RuntimeException("单日流水号超出!");
                }
                String i = StringUtil.addZeroForNum(String.valueOf(Integer.valueOf(index) + 1),
                        5);
                long flow =  Long.valueOf(flowNo + i);
                order.setId(flow);
            }
            switch (order.getMode()) {
                case 1: //支付宝
                    if(StringUtil.isNullOrEmpty(order.getPayCode())){
                        //离线支付宝支付
                        order.setStatus(4);
                        createBaseOrder(user, order);
                    }else {
                        alipayTwo(user, order);
                    }
                    break;
                case 2: //微信
                    if(StringUtil.isNullOrEmpty(order.getPayCode())){
                        //离线微信支付
                        order.setStatus(5);
                        createBaseOrder(user, order);
                    }else{
                        weixin(user, order);
                    }
                    break;
                case 3:
                    //银联
                    //union(user, order);
                    order.setStatus(1);
                    //银联支付
                    order.setMode(3);
                    createBaseOrder(user, order);
                    break;
                default: //基础订单
                    order.setStatus(1);
                    createBaseOrder(user, order);
                    break;
            }
            //减去订单数量
            subtract(order.getItems());
            list.add(String.valueOf(order.getId()));
        }
        return list;
    }


    @Override
    public String alipay(final AdminUser user, final PayOrder order) {
        if (Strings.isNullOrEmpty(order.getPayCode())) {
            throw new RuntimeException("支付宝用户付款码不存在!");
        }
        if(order.getStatus() == 1){
            throw new RuntimeException("订单支付方式异常!");
        }
        if(barCodePay(user, order)){
            order.setStatus(1);
            createBaseOrder(user, order);
            //返回订单的交易号.
            return order.getOnlineOrderSn();
        }
        throw new RuntimeException("支付宝,支付失败!");
    }

    @Override
    public String alipayTwo(AdminUser user, PayOrder order) {
        if (Strings.isNullOrEmpty(order.getPayCode())) {
            throw new RuntimeException("支付宝用户付款码不存在!");
        }
        if(order.getStatus() == 1){
            throw new RuntimeException("订单支付方式异常!");
        }
        if(barCodePay(user, order)){
            order.setStatus(1);
            createBaseOrderTwo(user, order);
            //返回订单的交易号.
            return order.getOnlineOrderSn();
        }
        throw new RuntimeException("支付宝,支付失败!");
    }

    /**
     * 支付宝支付
     * @param order
     * @return
     */
    private boolean barCodePay(final AdminUser adminUser, final PayOrder order) {

        // (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
        String outTradeNo = UUID.randomUUID().toString();

        //设置订单号
        order.setOnlineOrderSn(outTradeNo);

        // (必填) 订单标题，粗略描述用户的支付目的。如“喜士多（浦东店）消费”
        String subject=adminUser.getStoreName() + "门店消费";
//        if (null!=adminUser&&null==adminUser.getStoreName()){
//            subject +="门店消费";
//        }else{
//            subject = adminUser.getStoreName() + "门店消费";
//        }
//        if ("".equals(subject)){
//            subject +="门店消费";
//        }


        // (必填) 订单总金额，单位为元，不能超过1亿元 实际收
        String totalAmount = String.valueOf(order.getOfficialReceipts().doubleValue());

        // 订单描述，
        String body = "购买了" + order.getItems().size() + "件商品,消费" + totalAmount + "元.";


        // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
        String storeId = String.valueOf(adminUser.getUserId());

        // 商品明细列表，需填写购买商品详细信息，
        List<GoodsDetail> goodsDetailList = new ArrayList<>();

        ErpGoods goods;
        for(PayOrderItem item : order.getItems()){
            goods = erpGoodMapper.selectById(item.getGoodsId());
            GoodsDetail goods1;
            if(goods != null) {
                goods1 = GoodsDetail.newInstance("商品ID:" + goods.getGoodsId(), goods.getGoodsName(), item.getSinglePrice().multiply(new BigDecimal(100)).longValue(), (int)item.getGoodsNum());
            }else{
                goods1 = GoodsDetail.newInstance("自定义商品", "自定义商品", item.getSinglePrice().multiply(new BigDecimal(100)).longValue(), (int)item.getGoodsNum());
            }

            goodsDetailList.add(goods1);
        }

        // 支付超时，线下扫码交易定义为5分钟
        String timeoutExpress = "5m";

        logger.info("支付宝 authToken:{}", authToken);
        AlipayTradePayRequestBuilder builder = new AlipayTradePayRequestBuilder()
                .setOutTradeNo(outTradeNo)
                .setSubject(subject)
                .setBody(body)
                .setTotalAmount(totalAmount)
                .setAuthCode(order.getPayCode())
                .setTotalAmount(totalAmount)
                .setStoreId(storeId)
                .setGoodsDetailList(goodsDetailList)
                .setTimeoutExpress(timeoutExpress)
                .setAppAuthToken(authToken);

        // 当面付，面对面付，face to face pay -> face 2 face pay -> f2f pay
        // 同步返回支付结果

        AlipayF2FPayResult f2FPayResult = alipayTradeService.tradePay(builder);
        // 注意：一定要处理支付的结果，因为不是每次支付都一定会成功，可能会失败
        switch (f2FPayResult.getTradeStatus()) {
            case SUCCESS:
                logger.info("支付宝支付成功!");
                return true;

            case FAILED:
                logger.error("支付宝支付失败!!!");
                return false;

            case UNKNOWN:
                logger.error("系统异常，订单状态未知!!!");
                return false;

            default:
                logger.error("不支持的交易状态，交易返回异常!!!");
                return false;
        }
    }



    @Override
    public List<String> createBaseOrdersRepetition(String ordersn, AdminUser user, List<PayOrder> orders) {
        if (orders.isEmpty()) {
            throw new RuntimeException("没有需要更新的订单项");
        }

        //0: 现金 1:支付宝 2:微信 3:银联
        List<String> list = new ArrayList<>();
        for (PayOrder order : orders) {

            order.setId(Long.valueOf(ordersn));//订单编号

            switch (order.getMode()) {
                case 1: //支付宝
                    if(StringUtil.isNullOrEmpty(order.getPayCode())){
                        //离线支付宝支付
                        order.setStatus(4);
                        createBaseOrderTwo(user, order);
                    }else {
                        alipayTwo(user, order);
                    }
                    break;
                case 2: //微信
                    if(StringUtil.isNullOrEmpty(order.getPayCode())){
                        //离线微信支付
                        order.setStatus(5);
                        createBaseOrderTwo(user, order);
                    }else{
                        weixinTwo(user, order);
                    }
                    break;
                case 3:
                    //银联
                    //union(user, order);
                    order.setStatus(1);
                    //银联支付
                    order.setMode(3);
                    createBaseOrderTwo(user, order);
                    break;
                default: //基础订单
                    order.setStatus(1);
                    createBaseOrderTwo(user, order);
                    break;
            }
            //减去订单数量
            subtract(order.getItems());
            list.add(String.valueOf(order.getId()));
        }
        return list;
    }


    @Override
    public void weixin(final AdminUser user, final PayOrder order) {
        if(order.getStatus() == 1){
            throw new RuntimeException("订单支付方式异常!");
        }

        try{

            WXPayClient payClient =  payComponent.getWXPayClientByAdminUser(user);
            Map<String, String> reqData = new HashMap<>();
            // 商户订单号
            String outTradeNo = order.getId() + weixinProperties.getMchID();
            order.setOnlineOrderSn(outTradeNo);
            reqData.put("out_trade_no", outTradeNo);
            // 订单总金额，单位为分，只能为整数
            if(payClient.isUseSandBox()) {
                //301 or 302
                reqData.put("total_fee", "1");
            }else{
                reqData.put("total_fee", String.valueOf(order.getOfficialReceipts().multiply(new BigDecimal(100)).longValue()));
            }
            // 授权码
            reqData.put("auth_code", order.getPayCode());
            // 商品描述
            reqData.put("body", "购买了" + order.getItems().size() + "件商品,消费" + order.getOfficialReceipts() + "元.");
            reqData.put("sub_mch_id", ((WeixinProperties)payClient.getConfig()).getSubMchId());
            Map<String, String> resultMap = payClient.microPayWithPOS(reqData);
            logger.info(resultMap.toString());
            /*
             * 2019-04-09 15:08:59.383  INFO 8208 --- [  XNIO-2 task-7] c.zbl.zblproject.pay.service.PayService  :
             * {transaction_id=4200000262201904098199573370, nonce_str=7A0zM3bB3MeHjXyY,
             * bank_type=ICBC_DEBIT, openid=o_afN58jSy8pZpxKY8HJeSHA6KN0, sign=B90A20B7D9248A207823B3AC60079E14,
             * return_msg=OK, sub_is_subscribe=Y, fee_type=CNY, mch_id=1523919001, sub_mch_id=1527710801,
             * sub_appid=wxc374aff1503a8b59, cash_fee=1, sub_openid=o_afN58jSy8pZpxKY8HJeSHA6KN0,
             * out_trade_no=2019040901000191523919001, cash_fee_type=CNY, appid=wxc374aff1503a8b59,
             * total_fee=1, trade_type=MICROPAY, result_code=SUCCESS, attach=, time_end=20190409141626,
             * is_subscribe=Y, return_code=SUCCESS}
             * */


            if(null!=resultMap.get("err_code")&&!"".equals(resultMap.get("err_code"))){
                if(resultMap.get("err_code").equals("USERPAYING")){


                    logger.info("休眠2.5秒BEG");
                    Thread.sleep(2500);
                    logger.info("休眠2.5秒END");
//                    Map<String, String> resultMap1 = payClient.microPayWithPOS(reqData);
//                    if(WXPayConstants.SUCCESS.equals(resultMap1.get("result_code"))){

                     /*开始支付查询业务业务*/
                    Map<String, String> data = new HashMap<>();
                    data.put("out_trade_no", outTradeNo);
                    data.put("sub_mch_id", ((WeixinProperties)payClient.getConfig()).getSubMchId());
                    Map<String, String> resultTEMP = wxPay.orderQuery(data);
                    logger.info("第1次查询wxPay.orderQuery(data)="+resultTEMP.toString());
                    if(null!=resultTEMP.get("trade_state")&&!"".equals(resultTEMP.get("trade_state"))){
                        if(resultTEMP.get("trade_state").equals("SUCCESS")){
                               //支付成功
                            order.setStatus(1);
                            createBaseOrderTwo(user, order);
                            return;
                        }else if(resultTEMP.get("trade_state").equals("PAYERROR")){
                            //支付失败
                            order.setStatus(0);
                            createBaseOrderTwo(user, order);
                            return;
                        }



                    }


                    Thread.sleep(3000);//3秒



                    Map<String, String> resultTEMP1 = wxPay.orderQuery(data);
                    logger.info("第2次查询wxPay.orderQuery(data)="+resultTEMP1.toString());
                    if(null!=resultTEMP1.get("trade_state")&&!"".equals(resultTEMP1.get("trade_state"))){
                        if(resultTEMP1.get("trade_state").equals("SUCCESS")){
                            //支付成功
                            order.setStatus(1);
                            createBaseOrderTwo(user, order);
                            return;
                        }else if(resultTEMP.get("trade_state").equals("PAYERROR")){
                            //支付失败
                            order.setStatus(0);
                            createBaseOrderTwo(user, order);
                            return;
                        }

                    }



                    Thread.sleep(6000);//6秒



                    Map<String, String> resultTEMP2 = wxPay.orderQuery(data);
                    logger.info("第2次查询wxPay.orderQuery(data)="+resultTEMP2.toString());
                    if(null!=resultTEMP2.get("trade_state")&&!"".equals(resultTEMP2.get("trade_state"))){
                        if(resultTEMP2.get("trade_state").equals("SUCCESS")){
                            //支付成功
                            order.setStatus(1);
                            createBaseOrderTwo(user, order);
                            return;
                        }else if(resultTEMP.get("trade_state").equals("PAYERROR")){
                            //支付失败
                            order.setStatus(0);
                            createBaseOrderTwo(user, order);
                            return;
                        }

                    }

                    Thread.sleep(5000);//5秒



                    Map<String, String> resultTEMP3 = wxPay.orderQuery(data);
                    logger.info("第3次查询wxPay.orderQuery(data)="+resultTEMP3.toString());
                    if(null!=resultTEMP3.get("trade_state")&&!"".equals(resultTEMP3.get("trade_state"))){
                        if(resultTEMP3.get("trade_state").equals("SUCCESS")){
                            //支付成功
                            order.setStatus(1);
                            createBaseOrderTwo(user, order);
                            return;
                        }else{
                            order.setStatus(0);
                            createBaseOrderTwo(user, order);
                            return;

                        }

                    }





                                /*
                                * wxPay.orderQuery(data)={transaction_id=4200000328201904221817634493,
                                * nonce_str=Y9ZyOpP3BPJnsjU2,
                                * trade_state=SUCCESS,
                                * bank_type=ICBC_DEBIT,
                                * openid=o_afN58jSy8pZpxKY8HJeSHA6KN0,
                                * sign=205D64B7BA76DB3218FF4686884020EE,
                                 * return_msg=OK, sub_is_subscribe=Y,
                                 * fee_type=CNY, mch_id=1523919001,
                                 * sub_mch_id=1527710801,
                                 * sub_appid=wxc374aff1503a8b59,
                                 * cash_fee=1,
                                 * sub_openid=o_afN58jSy8pZpxKY8HJeSHA6KN0,
                                 * out_trade_no=2019042201000181523919001,
                                  * appid=wxc374aff1503a8b59, total_fee=1,
                                  * trade_state_desc=支付成功,
                                  * trade_type=MICROPAY, result_code=SUCCESS,
                                  * attach=, time_end=20190422174355, is_subscribe=Y, return_code=SUCCESS}
                                * */


                        //继续判断没有问题



//                    }


                }
            }
            if(WXPayConstants.SUCCESS.equals(resultMap.get("result_code"))){
                order.setStatus(1);
                createBaseOrder(user, order);
            }else{
                order.setStatus(0);
                createBaseOrder(user, order);
                throw new RuntimeException("微信订单支付失败!");
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
    @Autowired
    private WXPay wxPay;

    @Override
    public void weixinTwo(AdminUser user, PayOrder order) {
        if(order.getStatus() == 1){
            throw new RuntimeException("订单支付方式异常!");
        }

        try{
            WXPayClient payClient =  payComponent.getWXPayClientByAdminUser(user);
            Map<String, String> reqData = new HashMap<>();
            // 商户订单号
            String outTradeNo = order.getId() + weixinProperties.getMchID();
            order.setOnlineOrderSn(outTradeNo);
            reqData.put("out_trade_no", outTradeNo);
            // 订单总金额，单位为分，只能为整数
            if(payClient.isUseSandBox()) {
                //301 or 302
                reqData.put("total_fee", "1");
            }else{
                reqData.put("total_fee", String.valueOf(order.getOfficialReceipts().multiply(new BigDecimal(100)).longValue()));
            }
            // 授权码
            reqData.put("auth_code", order.getPayCode());
            // 商品描述
            reqData.put("body", "购买了" + order.getItems().size() + "件商品,消费" + order.getOfficialReceipts() + "元.");
            reqData.put("sub_mch_id", ((WeixinProperties)payClient.getConfig()).getSubMchId());
            Map<String, String> resultMap = payClient.microPayWithPOS(reqData);
            logger.info(resultMap.toString());

            if(null!=resultMap.get("err_code")&&!"".equals(resultMap.get("err_code"))){
                if(resultMap.get("err_code").equals("USERPAYING")){
                    if(resultMap.get("err_code").equals("USERPAYING")){


                        logger.info("休眠2.5秒BEG");
                        Thread.sleep(2500);
                        logger.info("休眠2.5秒END");
//                    Map<String, String> resultMap1 = payClient.microPayWithPOS(reqData);
//                    if(WXPayConstants.SUCCESS.equals(resultMap1.get("result_code"))){

                        /*开始支付查询业务业务*/
                        Map<String, String> data = new HashMap<>();
                        data.put("out_trade_no", outTradeNo);
                        data.put("sub_mch_id", ((WeixinProperties)payClient.getConfig()).getSubMchId());
                        Map<String, String> resultTEMP = wxPay.orderQuery(data);
                        logger.info("第1次查询wxPay.orderQuery(data)="+resultTEMP.toString());
                        if(null!=resultTEMP.get("trade_state")&&!"".equals(resultTEMP.get("trade_state"))){
                            if(resultTEMP.get("trade_state").equals("SUCCESS")){
                                //支付成功
                                order.setStatus(1);
                                createBaseOrderTwo(user, order);
                                return;
                            }else if(resultTEMP.get("trade_state").equals("PAYERROR")){
                                //支付失败
                                order.setStatus(0);
                                createBaseOrderTwo(user, order);
                                return;
                            }

                        }


                        Thread.sleep(3000);//3秒



                        Map<String, String> resultTEMP1 = wxPay.orderQuery(data);
                        logger.info("第2次查询wxPay.orderQuery(data)="+resultTEMP1.toString());
                        if(null!=resultTEMP1.get("trade_state")&&!"".equals(resultTEMP1.get("trade_state"))){
                            if(resultTEMP1.get("trade_state").equals("SUCCESS")){
                                //支付成功
                                order.setStatus(1);
                                createBaseOrderTwo(user, order);
                                return;
                            }else if(resultTEMP.get("trade_state").equals("PAYERROR")){
                                //支付失败
                                order.setStatus(0);
                                createBaseOrderTwo(user, order);
                                return;
                            }

                        }



                        Thread.sleep(6000);//6秒



                        Map<String, String> resultTEMP2 = wxPay.orderQuery(data);
                        logger.info("第2次查询wxPay.orderQuery(data)="+resultTEMP2.toString());
                        if(null!=resultTEMP2.get("trade_state")&&!"".equals(resultTEMP2.get("trade_state"))){
                            if(resultTEMP2.get("trade_state").equals("SUCCESS")){
                                //支付成功
                                order.setStatus(1);
                                createBaseOrderTwo(user, order);
                                return;
                            }else if(resultTEMP.get("trade_state").equals("PAYERROR")){
                                //支付失败
                                order.setStatus(0);
                                createBaseOrderTwo(user, order);
                                return;
                            }

                        }

                        Thread.sleep(5000);//5秒



                        Map<String, String> resultTEMP3 = wxPay.orderQuery(data);
                        logger.info("第3次查询wxPay.orderQuery(data)="+resultTEMP3.toString());
                        if(null!=resultTEMP3.get("trade_state")&&!"".equals(resultTEMP3.get("trade_state"))){
                            if(resultTEMP3.get("trade_state").equals("SUCCESS")){
                                //支付成功
                                order.setStatus(1);
                                createBaseOrderTwo(user, order);
                                return;
                            }else{
                                order.setStatus(0);
                                createBaseOrderTwo(user, order);
                                return;

                            }

                        }





                        /*
                         * wxPay.orderQuery(data)={transaction_id=4200000328201904221817634493,
                         * nonce_str=Y9ZyOpP3BPJnsjU2,
                         * trade_state=SUCCESS,
                         * bank_type=ICBC_DEBIT,
                         * openid=o_afN58jSy8pZpxKY8HJeSHA6KN0,
                         * sign=205D64B7BA76DB3218FF4686884020EE,
                         * return_msg=OK, sub_is_subscribe=Y,
                         * fee_type=CNY, mch_id=1523919001,
                         * sub_mch_id=1527710801,
                         * sub_appid=wxc374aff1503a8b59,
                         * cash_fee=1,
                         * sub_openid=o_afN58jSy8pZpxKY8HJeSHA6KN0,
                         * out_trade_no=2019042201000181523919001,
                         * appid=wxc374aff1503a8b59, total_fee=1,
                         * trade_state_desc=支付成功,
                         * trade_type=MICROPAY, result_code=SUCCESS,
                         * attach=, time_end=20190422174355, is_subscribe=Y, return_code=SUCCESS}
                         * */


                        //继续判断没有问题



//                    }


                    }
                }
            }

            logger.info("微信支付情况：----"+resultMap.get("result_code"));


            if(WXPayConstants.SUCCESS.equals(resultMap.get("result_code"))){

                order.setStatus(1);
                createBaseOrderTwo(user, order);
            }else{
                order.setStatus(0);
                createBaseOrderTwo(user, order);
                throw new RuntimeException("微信订单支付失败!");
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }

    }

    @Override
    public void union(final AdminUser user, final PayOrder order) {
        //TODO 银联接口未完成
        throw new RuntimeException("银联接口未完成!");
    }


    @Override
    public BigDecimal returnAlipayItems(PayOrder order, List<PayOrderItem> list) {
        return null;
    }

    @Override
    public String getPayOrderOnlineOrder(String orderSn) {
        return payOrderMapper.selectOnlineOrderOfPayOrder(orderSn);
    }

    @Override
    public JSONArray todaySuccessPayOrders(String orderSn, int userId) {
        //SELECT * FROM zbl_pay_order WHERE TO_DAYS(create_time) = TO_DAYS(now()) AND status = 1;
        JSONArray jsonArray = new JSONArray();
        List<PayOrder> list = null;
        if(StringUtil.isNullOrEmpty(orderSn)||orderSn.equals("-1")){
            list = payOrderMapper.selectTodayOrder(userId);
            for (PayOrder payOrder:list){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id",payOrder.getId());
                jsonObject.put("createTime",payOrder.getCreateTime());
                List<PayOrderItemVo> payOrderItemVos = payOrderItemMapper.selectOrderItemVos(payOrder.getId());
                jsonObject.put("list",payOrderItemVos);
                jsonArray.add(jsonObject);
            }
        }else{
            list = payOrderMapper.getOrderListBySns(userId,orderSn.trim());
            for (PayOrder payOrder:list){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id",payOrder.getId());
                jsonObject.put("createTime",payOrder.getCreateTime());
                List<PayOrderItemVo> payOrderItemVos = payOrderItemMapper.selectOrderItemVos(payOrder.getId());
                jsonObject.put("list",payOrderItemVos);
                jsonArray.add(jsonObject);
            }
        }
        return jsonArray;
    }

    @Override
    public JSONObject payOrderInfo(String orderSn) {
        JSONObject result = new JSONObject();
        // $("#receipt").attr("src","receipt.html?goodsList="+JSON.stringify(app.goodsList)+"&realMoney="+app.realMoney+"&sn="+data.data[0]+"&username="+app.basedata.putin_user+"&pay_type="+app.mode);
        List<PayOrder> payOrderList = payOrderMapper.selectPayOrderByIdList(Long.valueOf(orderSn));
        PayOrder payOrder = null;
        String strMode = "";
        List<PayList> payList = new ArrayList<>();
        Double officialReceipts = 0.0;//实收金额
        for (PayOrder payOrder1 : payOrderList) {
            officialReceipts += payOrder1.getOfficialReceipts().doubleValue();
        }
        if (payOrderList.size() == 1) {
            payOrder = payOrderList.get(0);
            strMode += payOrder.getMode();
            PayList payList1 = new PayList();
            payList1.setPayModel(payOrderList.get(0).getMode());
            payList1.setPayMoney(payOrderList.get(0).getOfficialReceipts().doubleValue());
            payList.add(payList1);
        } else {
            payOrder = payOrderList.get(0);
            for (PayOrder payOrder1 : payOrderList) {
                strMode += payOrder1.getMode();
                PayList payList1 = new PayList();
                payList1.setPayModel(payOrder1.getMode());
                payList1.setPayMoney(payOrder1.getOfficialReceipts().doubleValue());
                payList.add(payList1);
            }
        }
        //realMoney,username, app.mode
        //实收金额
//        System.out.println("modes:"+JSON.parseArray(JSONArray.toJSONString(te)));


        result.put("mode", strMode);

        result.put("payList",payList);

        result.put("realMoney", officialReceipts);

        result.put("username", adminUserMapper.selectNameById(payOrder.getUserId()));
        result.put("discount", payOrder.getDiscount());

        result.put("createTime",payOrder.getCreateTime());
        JSONArray goodsList = new JSONArray();
        List<PayOrderItem> items = payOrderItemMapper.selectListByOrderId(payOrder.getId());

        //app.temp.goodsId = data.data.goodsId;
        //app.temp.goodNum = 1;
        //app.temp.goodsName = data.data.goodsName;
        //app.temp.brandName = data.data.erpBrand.brandName;
        //app.temp.marketPrice = data.data.marketPrice;
        //app.temp.totalMoney = new Decimal(app.temp.goodNum).mul(new Decimal(app.temp.marketPrice)).toFixed(2);
        //app.total=new Decimal(app.temp.goodNum).mul(new Decimal(app.temp.marketPrice)).toFixed(2);
        for(PayOrderItem item : items){
            JSONObject object = new JSONObject();
            object.put("goodsId", item.getGoodsId());
            object.put("goodNum", item.getGoodsNum());
            object.put("goodsName", item.getGoodsName());
            object.put("brandName", erpGoodMapper.getBrandNameByGoodsId(item.getGoodsId()));
            object.put("marketPrice", item.getSinglePrice());
            object.put("totalMoney", item.getSinglePrice().multiply(BigDecimal.valueOf(item.getGoodsNum())));
            object.put("goodsSn", erpGoodMapper.selectGoodsSn(item.getGoodsId()));
            object.put("discount", item.getDiscount());
            goodsList.add(object);
        }
        result.put("goodsList", goodsList);
        return result;
    }

    public JSONObject  salesPage(LocalDateTime start, LocalDateTime end, int useId,String goodsName,int catId,int supId){
        JSONObject jsonObject = new JSONObject();
        List<PayOrderItemVo> orderItemVos = payOrderItemMapper.selectListByTimeAndUserId(start, end, useId,goodsName, catId, supId);
        List<PayOrder> orders = payOrderMapper.selectOrderAll(useId,-1,start,end);

        double num =0;
        double prices=0;//金额
        for (PayOrder order:orders){
            prices +=order.getOfficialReceipts().doubleValue();
        }
        double lirun=0;//利润
        for (PayOrderItemVo orderItemVo1:orderItemVos){
            num +=orderItemVo1.getGoodsNum();
            try {
                if (orderItemVo1.getShopPrice()!=null){
                    lirun +=(orderItemVo1.getSinglePrice().doubleValue()*orderItemVo1.getDiscount().doubleValue()-orderItemVo1.getShopPrice().doubleValue())
                            *orderItemVo1.getGoodsNum();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        for (int i=0;i<orderItemVos.size();i ++){
            if (null==orderItemVos.get(i).getGoodsSn()){
                orderItemVos.get(i).setGoodsSn("");
            }
            if (null==orderItemVos.get(i).getCode()){
                orderItemVos.get(i).setCode("");
            }
            if (null==orderItemVos.get(i).getSupName()){
                orderItemVos.get(i).setSupName("");
            }
            if (null==orderItemVos.get(i).getCatName()){
                orderItemVos.get(i).setCatName("");
            }
            if (null==orderItemVos.get(i).getShopPrice()){
                orderItemVos.get(i).setShopPrice(orderItemVos.get(i).getSinglePrice());
            }
        }
        jsonObject.put("list",orderItemVos);
        jsonObject.put("num",num);
        jsonObject.put("prices",prices);
        jsonObject.put("lirun",lirun);
//        List<PayOrderItem> orderItems = payOrderItemMapper.selectListByTimeAndUserId(start, end, useId,goodsName, catId, supId);
//        JSONObject result = new JSONObject();
//        //订单数量总计, 金额数量, 商品数量
//        double num=0;//数量
//        double pirces=0;//金额
//        double lirun=0;//利润
//        List<JSONObject> items = new ArrayList<>();
//
//        int allNumber = 0;
//        BigDecimal allPrice = BigDecimal.ZERO;
//        Set<Long> orders = new TreeSet<>();
//
//        for(PayOrderItem orderItem : orderItems){
//            num +=orderItem.getGoodsNum();
//            pirces +=orderItem.getPirces();
//            JSONObject item = new JSONObject();
//            item.put("orderId", orderItem.getOrderId());
//            orders.add(orderItem.getOrderId());
//            item.put("goodsId", orderItem.getGoodsId());
//            item.put("goodsName", orderItem.getGoodsName());
//            item.put("singlePrice", orderItem.getSinglePrice());
//            item.put("goodsNum", orderItem.getGoodsNum());
//            allNumber += orderItem.getGoodsNum();
//            item.put("totalMoney", orderItem.getSinglePrice().multiply(BigDecimal.valueOf(orderItem.getGoodsNum())));
//            allPrice = allPrice.add(item.getBigDecimal("totalMoney"));
//            String unit = smallUnitMapper.selectUnitNameByGoodsId(orderItem.getGoodsId());
//            if(unit == null){
//                item.put("unit", "个");
//            }else{
//                item.put("unit", unit);
//            }
//            //入库价, 小编码, 大编码
//            ErpGoods goods = erpGoodMapper.selectById(orderItem.getGoodsId());
//            // shopPrice 入库价
//            // commodityCode 小编码
//            // goodsSn 大编码
//            if(goods != null){
//                item.put("shopPrice", goods.getShopPrice());
//                item.put("commodityCode", goods.getCommodityCode());
//                item.put("goodsSn", goods.getGoodsSn());
//                lirun += pirces-orderItem.getGoodsNum()*goods.getShopPrice().doubleValue();
//            }else{
//                item.put("shopPrice", 0.0);
//                item.put("commodityCode", "无");
//                item.put("goodsSn", "无");
//            }
//            if(orderItem.getGoodsId() != 0){
//                item.put("supplierName", Optional.ofNullable(supplierMapper.selectSupplierNameByGoodsId(orderItem.getGoodsId())).orElse("无"));
//                item.put("brandName", Optional.ofNullable(erpGoodMapper.getBrandNameByGoodsId(orderItem.getGoodsId())).orElse("无"));
//                item.put("cateName", Optional.ofNullable(erpCategoryMapper.selectCateNameByGoodsId(orderItem.getGoodsId())).orElse("无"));
//            }else{
//                item.put("supplierName", "无");
//                item.put("brandName", "无");
//                item.put("cateName", "无");
//            }
//            items.add(item);
//        }
//        result.put("list", items);
//        result.put("allGoodsNumber", allNumber);
//        result.put("allPrice", allPrice);
//        result.put("ordersNumber", orders.size());
//        result.put("num",num);
//        result.put("lirun",lirun);
//        result.put("pirces",pirces);

        return jsonObject;
    }

    @Override
    public JSONObject pageForOrderList(LocalDateTime start, LocalDateTime end, int userId, int current, int size, int mode){
//        IPage<PayOrder> order = new Page<>(current, size);
//        QueryWrapper<PayOrder> wrapper = new QueryWrapper<>();
//        wrapper.between("create_time", start, end);
//        if(userId != -1){
//            wrapper.eq("user_id", userId);
//        }
//        if(mode != -1){
//            wrapper.eq("mode", mode);
//        }
//        order = payOrderMapper.selectPage(order, wrapper);
        double receivable=0;
        double official_receipts=0;
        double change_note=0;
        JSONObject jsonObject =new JSONObject();
        PageHelper.startPage(current,size);
        List<PayOrder> payOrderList = payOrderMapper.selectOrderAll(userId,mode,start,end);
        for (PayOrder payOrder:payOrderList){
            receivable +=payOrder.getReceivable().doubleValue();
            official_receipts +=payOrder.getOfficialReceipts().doubleValue();
            change_note +=payOrder.getChangeNote().doubleValue();
        }
        PageInfo pageInfo = new PageInfo(payOrderList);
        jsonObject.put("list",pageInfo);
        jsonObject.put("receivable",receivable);
        jsonObject.put("official_receipts",official_receipts);
        jsonObject.put("change_note",change_note);
        return jsonObject;
    }

    @Override
    public void synOrder(List<PayOrder> orders) {
        //将不存在的订单备份到数据库中
        for(PayOrder order : orders){
            PayOrder item = payOrderMapper.selectById(order.getId());
            if(item == null){
                payOrderMapper.insert(order);
                List<PayOrderItem> children = order.getItems();
                for(PayOrderItem child : children){
                    //删除对应的商品数量
                    erpGoodMapper.subGoodsNum(child.getGoodsId(), (int)child.getGoodsNum());
                    payOrderItemMapper.insert(child);
                }
            }
        }
    }


    @Override
    public List<StatisticsTable> getStatisticsTable(LocalDateTime start, LocalDateTime end, Integer userId) {
        // 0: 现金 1:支付宝 2:微信 3:银联 4:离线支付宝支付 5:离线微信支付
        List<StatisticsTable> list = new ArrayList<>();
        for(int i = 0; i < 6; i++){
            StatisticsTable table = new StatisticsTable();
            table.setMode(i);
            table.setUserId(userId);
            //付款次数
            table.setPayTimes(payOrderMapper.selectPayTimes(userId, i, start, end));
            //付款金额
            table.setPrice(payOrderMapper.selectPayMoney(userId, i, start, end));
            list.add(table);
        }

        return list;
    }
}
